package com.fling.entity;

import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.fling.Locator;

public abstract class CollisionEntity extends Entity {

	protected Body body;
	protected BodyDef bodyDef;
	protected FixtureDef bodyFixture;
	protected TYPE type;
	protected float scale;

	public CollisionEntity(Vector2 position, TYPE t, String path, boolean isStatic, boolean sensor) {
		this(position, t, path, isStatic, sensor, 1);
	}

	public CollisionEntity(Vector2 position, TYPE t, String path, boolean isStatic, boolean sensor, float scale) {
		this(1,1,position,t,path,isStatic,sensor,scale);
	}
	public CollisionEntity(float cols, float rows, Vector2 position, TYPE t, String path, boolean isStatic, boolean sensor, float scale){
		super(position, path);
		type = t;
		this.scale = scale;
		bodyDef = new BodyDef();
		bodyFixture = new FixtureDef();
		if (!isStatic) {
			bodyDef.type = BodyType.DynamicBody;
		} else {
			bodyDef.type = BodyType.StaticBody;
		}
		bodyDef.position.set(new Vector2(position.x + sprite.getWidth() / cols * SCALE * scale * Locator.getxSpriteScale() / 2, position.y
				+ sprite.getHeight() / rows * SCALE * scale * Locator.getySpriteScale() / 2));
		bodyDef.fixedRotation = true;

		body = Locator.getWorld().createBody(bodyDef);

		PolygonShape shape = new PolygonShape();
		shape.setAsBox(sprite.getWidth() / cols / 2 * SCALE * this.scale * Locator.getxSpriteScale(),
				sprite.getHeight() / rows / 2 * SCALE * this.scale * Locator.getySpriteScale());
		bodyFixture.shape = shape;
		if (sensor) {
			bodyFixture.isSensor = true;
		}
		body.setLinearDamping(8.0f);

		body.createFixture(bodyFixture);
		body.setUserData(this);
	}

	@Override
	public void setPosition(Vector2 position) {
		body.setTransform(position.x + sprite.getWidth() * SCALE * scale * Locator.getxSpriteScale() / 2, position.y + sprite.getHeight() * SCALE
				* scale * Locator.getySpriteScale() / 2, 0);
	}

	public void update(float delta) {
		body.setTransform(body.getPosition(), direction);
		position = body.getPosition();
	}

	public void render(SpriteBatch sb) {
		sb.draw(sprite.getTexture(), body.getPosition().x - sprite.getWidth() * 0.5f, body.getPosition().y - sprite.getHeight() * 0.5f,
				sprite.getWidth() * 0.5f, sprite.getHeight() * 0.5f, sprite.getWidth(), sprite.getHeight(),
				SCALE * scale * Locator.getxSpriteScale(), SCALE * scale * Locator.getySpriteScale(), 0, 0, 0, (int) sprite.getWidth(),
				(int) sprite.getHeight(), flipX, flipY);
	}
	
	public void render(SpriteBatch sb, Sprite sp) {
		sb.draw(sp.getTexture(), body.getPosition().x - sp.getWidth() * 0.5f, body.getPosition().y - sp.getHeight() * 0.5f,
				sp.getWidth() * 0.5f, sp.getHeight() * 0.5f, sp.getWidth(), sp.getHeight(),
				SCALE * scale * Locator.getxSpriteScale(), SCALE * scale * Locator.getySpriteScale(), 0, 0, 0, (int) sp.getWidth(),
				(int) sp.getHeight(), flipX, flipY);
	}

	// this render function renders sprites with an alpha
	public void render(SpriteBatch sb, float alpha) {
		sb.setColor(sb.getColor().r, sb.getColor().g, sb.getColor().b, alpha);
		sb.draw(sprite.getTexture(), body.getPosition().x - sprite.getWidth() * 0.5f, body.getPosition().y - sprite.getHeight() * 0.5f,
				sprite.getWidth() * 0.5f, sprite.getHeight() * 0.5f, sprite.getWidth(), sprite.getHeight(),
				SCALE * scale * Locator.getxSpriteScale(), SCALE * scale * Locator.getySpriteScale(), 0, 0, 0, (int) sprite.getWidth(),
				(int) sprite.getHeight(), flipX, flipY);
		sb.setColor(sb.getColor().r, sb.getColor().g, sb.getColor().b, 1.0f);
	}

	public void delete() {
		super.delete();
		Locator.getWorld().destroyBody(body);
		body = null;
	}

	public abstract void collide(CollisionEntity otherBody);

	public Body getBody() {
		return body;
	}

	public void setBody(Body body) {
		this.body = body;
	}

	public FixtureDef getBodyFixture() {
		return bodyFixture;
	}

	public void setBodyFixture(FixtureDef bodyFixture) {
		this.bodyFixture = bodyFixture;
	}

	public TYPE getType() {
		return type;
	}

	public void setType(TYPE type) {
		this.type = type;
	}

}
